package javablackbelt.dao.jdbc;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

import javablackbelt.dao.UserDao;
import javablackbelt.domain.User;

import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;

public class UserJdbcDao extends SimpleJdbcDaoSupport implements UserDao {

	
	public final ParameterizedRowMapper<User> userMapper = new UserMapper();
	
	private AtomicLong idGenerator = new AtomicLong();
	
	public void delete(User user) {
		getSimpleJdbcTemplate().update("DELETE FROM USERS WHERE ID = ?", 
								 new Object[] {user.getId()});
	}

	public void deleteAll() {
		getJdbcTemplate().update("DELETE FROM USERS", (Object[])null);
	}

	public List<User> findByFirstLetterOfLastName(char letter) {
		MapSqlParameterSource sqlParameters = new MapSqlParameterSource();
		sqlParameters.addValue("wc", "%" + letter + "%");
		
		return getSimpleJdbcTemplate().query("SELECT * FROM USERS WHERE LAST_NAME LIKE :wc", userMapper, sqlParameters);
	}

	public User get(Long id) {
		return getSimpleJdbcTemplate().queryForObject("SELECT * FROM USERS WHERE ID = ?", userMapper, new Object[] {id});
	}

	public List<User> getAll() {
		return getSimpleJdbcTemplate().query("SELECT * FROM USERS", userMapper, (Object[])null);
	}

	public void save(User user) {
		
		if (user == null) {
			throw new IllegalArgumentException("User must not be null.");
		}

		// update
		if (user.getId() != null) {
			getSimpleJdbcTemplate().update("UPDATE USERS SET FIRST_NAME = ?, LAST_NAME = ? WHERE ID = ?", 
					new Object[] {user.getFirstName(),
								  user.getLastName(),
								  user.getId()});
		}
		// save
		else {
			Long newId = idGenerator.getAndIncrement();
			getSimpleJdbcTemplate().update("INSERT INTO USERS (ID, FIRST_NAME, LAST_NAME) VALUES(?,?,?)", 
					new Object[] {newId,
								  user.getFirstName(),
								  user.getLastName()});
			user.setId(newId);
		}
	}

	public class UserMapper implements ParameterizedRowMapper<User> {

		public User mapRow(ResultSet rs, int pos) throws SQLException {
			User user = new User();
			user.setId(rs.getLong("ID"));
			user.setFirstName(rs.getString("FIRST_NAME"));
			user.setLastName(rs.getString("LAST_NAME"));
			return user;
		}
		
	}
}
